/**
 * @author David Culyba, Dennis Cosgrove
 */

package edu.cmu.cs.stage3.alice.authoringtool.dialog;

import edu.cmu.cs.stage3.resourceBundle.I18n;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.io.File;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;

import edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool;
import edu.cmu.cs.stage3.swing.ContentPane;
import edu.cmu.cs.stage3.util.StringObjectPair;

class AliceWorldFilter implements java.io.FileFilter {

 private javax.swing.filechooser.FileFilter m_filter;
 public AliceWorldFilter(javax.swing.filechooser.FileFilter filter) {
  m_filter = filter;
  }
 public boolean accept (java.io.File file) {
  if (m_filter != null) {
   if (file.isDirectory()) {
    return true;
    }
   return m_filter.accept(file);
   }
  return false;
  }
 }

public class StartUpContentPane extends ContentPane { 
 public static final int DO_NOT_CHANGE_TAB_ID = -1;
 public static final int OPEN_TAB_ID = 1;

 private static final String OPEN_STRING = I18n.getString("startUpOpen"); // "Open a world"

 private final int WIDTH = 480;
 private final int HEIGHT = 470;
 private static final java.awt.Color SELECTED_COLOR = new java.awt.Color(10, 10, 100);
 private static final java.awt.Color SELECTED_TEXT_COLOR = new java.awt.Color(255, 255, 255);
 private static final java.awt.Color BACKGROUND_COLOR = new java.awt.Color(0, 0, 0);

 private AliceWorldFilter aliceFilter;
 private javax.swing.filechooser.FileFilter worldFilter;

 private StartUpIcon currentlySelected;

 private javax.swing.ImageIcon headerImage;
 private javax.swing.ImageIcon basicIcon;
 private javax.swing.ImageIcon directoryIcon;
 private javax.swing.ImageIcon upDirectoryIcon;

 private JTabbedPane mainTabPane = new JTabbedPane();

 private JButton openButton = new JButton();
 private JButton cancelButton = new JButton();
 private JButton refreshButton = new JButton();
 private JCheckBox stopShowingCheckBox = new JCheckBox();

 private JLabel headerLabel = new JLabel();

 private JFileChooser fileChooser = new JFileChooser() {
  //Rem @Override
  public void setSelectedFile( java.io.File file) {
   super.setSelectedFile( file );
   StartUpContentPane.this.handleFileSelectionChange( file );
   }
  };

 private JPanel buttonPanel = new JPanel();
 protected int currentTab = OPEN_TAB_ID;

 // Came from: edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool.fileInit()
 public StartUpContentPane (AuthoringTool authoringTool) {
  headerImage = new javax.swing.ImageIcon(edu.cmu.cs.stage3.alice.authoringtool.JAlice.class.getResource("images/startUpDialog/StartupScreen.png"));
  basicIcon = new javax.swing.ImageIcon(edu.cmu.cs.stage3.alice.authoringtool.JAlice.class.getResource("images/startUpDialog/aliceIcon.png"));
  directoryIcon = new javax.swing.ImageIcon(edu.cmu.cs.stage3.alice.authoringtool.JAlice.class.getResource("images/startUpDialog/directoryIcon.png"));
  upDirectoryIcon = new javax.swing.ImageIcon(edu.cmu.cs.stage3.alice.authoringtool.JAlice.class.getResource("images/startUpDialog/upDirectoryIcon.png"));
  // try{String str1=""; System.out.println(str1.charAt(3));}catch(Exception e){e.printStackTrace(); }

  worldFilter = authoringTool.getWorldFileFilter();
  aliceFilter = new AliceWorldFilter(worldFilter);

  jbInit();
  guiInit();

  addComponentListener( new java.awt.event.ComponentAdapter() {
   //Rem @Override
   public void componentResized( java.awt.event.ComponentEvent e) { }
   } );
  }

 //Rem @Override
 public void preDialogShow (javax.swing.JDialog dialog) {
  super.preDialogShow(dialog);
  mainTabPane.setSelectedComponent(getTabForID(currentTab));
  }

 private void handleFileSelectionChange (java.io.File file) {
  openButton.setEnabled( file!=null && file.exists() && !file.isDirectory() );
  }
 //todo? isResizable() return false;

 //todo: adjust title based on tab
 //Rem @Override
 public String getTitle () {
  return I18n.getString("startUpWelcome"); // "Welcome to iVprog/Alice!"
  }
 //Rem @Override
 public void addOKActionListener (java.awt.event.ActionListener l) {
  openButton.addActionListener( l );
  }
 //Rem @Override
 public void removeOKActionListener (java.awt.event.ActionListener l) {
  openButton.removeActionListener( l );
  }
 //Rem @Override
 public void addCancelActionListener (java.awt.event.ActionListener l) {
  cancelButton.addActionListener( l );
  }
 //Rem @Override
 public void removeCancelActionListener (java.awt.event.ActionListener l) {
  cancelButton.removeActionListener( l );
  }

 public boolean isSaveNeeded () {
  if (currentlySelected != null) {
   return currentlySelected.needToSave;
  } else {
   return true;
   }
  }
 public java.io.File getFile () {
  if (getTabID() == OPEN_TAB_ID) {
   return fileChooser.getSelectedFile();
  } else {
   if (currentlySelected != null) {
    return new java.io.File( currentlySelected.file );
   } else {
    return null;
    }
   }
  }

 private int getIDForTab (java.awt.Component tab) {
  if (tab == fileChooser)
   return OPEN_TAB_ID;
  return 0;
  }

 private java.awt.Component getTabForID (int tabID) {
  return fileChooser;
  }

 private int getTabID () {
  return getIDForTab( mainTabPane.getSelectedComponent() );
  }

 public void setTabID (int tabID) {
  if (tabID == OPEN_TAB_ID) {
   fileChooser.rescanCurrentDirectory();
   }
  if (tabID != DO_NOT_CHANGE_TAB_ID) {
   currentTab = tabID; 
   mainTabPane.setSelectedComponent(getTabForID(currentTab));
   }
  }

 private String makeNameFromFilename (String filename) {
  String name = filename.substring(0, (filename.length() - 4));
  int last = name.lastIndexOf(java.io.File.separator);
  if (last >= 0 && last < name.length()) {
   name = name.substring(last + 1);
   }
  return name;
  }

 private String makeDirectoryNameFromFilename (String filename) {
  String name = new String(filename);
  if (filename.endsWith(java.io.File.separator)) {
   filename = filename.substring(filename.length());
   }
  int last = filename.lastIndexOf(java.io.File.separator);
  if (last >= 0 && last < filename.length()) {
   name = filename.substring(last + 1);
   }
  return name;
  }

 private java.util.Vector buildVectorFromDirectory (java.io.File dir, java.io.FileFilter f) {
  java.util.Vector toReturn = null;
  if (dir != null && dir.isDirectory()) {
   toReturn = new java.util.Vector();
   java.io.File[] files = dir.listFiles(f);
   //LOB for (File file : files)
   int t_tam = files!=null ? files.length : 0;
   for (int i_i=0; i_i<t_tam; i_i++) {
    String name = "";
    if (files[i_i].isDirectory()) { //L file.isDirectory()
     name = makeDirectoryNameFromFilename(files[i_i].getName()); //L (file.getName())
    } else {
     name = makeNameFromFilename(files[i_i].getName()); //L (file.getName())
    }
    StringObjectPair sop = new StringObjectPair(name, files[i_i].getAbsolutePath()); //L file.getAbsolutePath()
    toReturn.add(sop);
    }
   }
  return toReturn;
  }

 private javax.swing.ImageIcon getIconFromFile (java.io.File file) {
  String filename = file.getAbsolutePath();
  javax.swing.ImageIcon icon = null;
  try {
   if (filename.endsWith(".stl")) {
    javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
    org.w3c.dom.Document document;
    javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
    document = builder.parse(file);
    org.w3c.dom.NodeList nl = document.getElementsByTagName("stencilStack");
    if (nl != null && nl.getLength() > 0) {
     org.w3c.dom.Node n = nl.item(0);
     if (n instanceof org.w3c.dom.Element) {
      String worldFileName = ((org.w3c.dom.Element) n).getAttribute("world");
      file = new java.io.File(worldFileName);
      }
     }
    }
   java.util.zip.ZipFile zip = new java.util.zip.ZipFile(file);
   java.util.zip.ZipEntry entry = zip.getEntry("thumbnail.png");
   if (entry != null) {
    zip.getInputStream(entry);
    }
   zip.close();
  } catch (Exception e) {
   return null;
   }
  return icon;
  }

 protected java.awt.Component getTopContainer (java.awt.Component innerContainer) {
  return null;
  }

 protected String getBaseDirString (java.awt.Component topLevelOwner) {
  return "";
  }

 private int buildPanel (javax.swing.JPanel toBuild, java.util.Vector toAdd, boolean needToSave, java.io.File parentDir, int type) {
  int count = 0;
  if (parentDir != null || toAdd != null) {
   toBuild.removeAll();
   }
  if (parentDir != null) {
   String parentDirName = I18n.getString("startUpBack"); // "Back"
   StartUpIcon parentDirIcon = new StartUpIcon(parentDirName, upDirectoryIcon, parentDir.getAbsolutePath(), false, StartUpIcon.DIRECTORY, getTopContainer(toBuild));
   toBuild.add(parentDirIcon);
   count++;
   }
  if (toAdd != null) {
   for (int i = 0; i < toAdd.size(); i++) {
    StringObjectPair sop = (StringObjectPair) toAdd.get(i);
    String name = sop.getString();
    String filename = (String) sop.getObject();
    java.io.File file = new java.io.File(filename);
    javax.swing.ImageIcon icon = basicIcon;
    if (file.exists() && file.canRead()) {
     filename = file.getAbsolutePath();
     if (file.isDirectory()) {
      StartUpIcon dirIcon = new StartUpIcon(name, directoryIcon, filename, false, StartUpIcon.DIRECTORY, getTopContainer(toBuild));
      toBuild.add(dirIcon);
      count++;
     } else {
      boolean worldIsThere = true;
      if (file.exists() && file.canRead()) {
       icon = getIconFromFile(file);
       if (icon == null) {
        icon = basicIcon;
        }
      } else {
       worldIsThere = false;
       }
      if (worldIsThere) {
       StartUpIcon sui = new StartUpIcon(name, icon, filename, needToSave, type, getTopContainer(toBuild));
       toBuild.add(sui);
       count++;
       }
      }
     }
    }
   }
  toBuild.revalidate();
  return count;
  }

 private void initializeFileChooser () {
  mainTabPane.remove(fileChooser);
  java.io.File currentDir = fileChooser.getCurrentDirectory();
  fileChooser = new JFileChooser () {
   //Rem @Override
   public void setSelectedFile( java.io.File file) {
    super.setSelectedFile( file );
    StartUpContentPane.this.handleFileSelectionChange( file );
    }
   };
  for (int i = 0; i < fileChooser.getComponentCount(); i++) {
   setButtonBackgroundColors(fileChooser.getComponent(i), fileChooser.getBackground());
   }
  if (currentDir.exists()) {
   fileChooser.setCurrentDirectory(currentDir);
   }
  fileChooser.setFileFilter(worldFilter);
  fileChooser.setBackground(Color.white);
  fileChooser.addActionListener(new java.awt.event.ActionListener() {
   public void actionPerformed(ActionEvent e) {
    fileChooser_actionPerformed(e);
    }
   });
  fileChooser.setFileSelectionMode( javax.swing.JFileChooser.FILES_ONLY );
  mainTabPane.add(fileChooser, OPEN_STRING);
  }

 private void guiInit () {
  setPreferredSize(new java.awt.Dimension(WIDTH, HEIGHT));
  headerLabel.setIcon(headerImage);
  mainTabPane.setUI(new edu.cmu.cs.stage3.alice.authoringtool.util.AliceTabbedPaneUI());
  mainTabPane.setOpaque(false);
  initializeFileChooser();
  }

 private void setButtonBackgroundColors (java.awt.Component c, java.awt.Color color) {
  if (!(c instanceof java.awt.Button)) {
   c.setBackground(color);
   }
  if (c instanceof java.awt.Container) {
   java.awt.Container cont = (java.awt.Container) c;
   for (int i = 0; i < cont.getComponentCount(); i++) {
    setButtonBackgroundColors(cont.getComponent(i), color);
    }
   }
  }

 private void jbInit () {
  setLayout(new GridBagLayout());
  Box.createGlue();
  Box.createGlue();
  buttonPanel.setLayout(new GridBagLayout());
  setBackground(Color.white);
  mainTabPane.setMinimumSize(new Dimension(480, 310));
  mainTabPane.setPreferredSize(new Dimension(480, 310));
  mainTabPane.addChangeListener(new javax.swing.event.ChangeListener() {
   public void stateChanged(ChangeEvent e) {
    mainTabPane_stateChanged(e);
   }
  });
  buttonPanel.setOpaque(false);
  openButton.setMaximumSize(new Dimension(95, 27));
  openButton.setMinimumSize(new Dimension(95, 27));
  openButton.setPreferredSize(new Dimension(95, 27));
  openButton.setText(I18n.getString("startUpOpen")); // "Open"

  cancelButton.setMaximumSize(new Dimension(95, 27));
  cancelButton.setMinimumSize(new Dimension(95, 27));
  cancelButton.setPreferredSize(new Dimension(95, 27));
  cancelButton.setText(I18n.getString("msgCancel")); 

  refreshButton.setMaximumSize(new Dimension(90, 22));
  refreshButton.setMinimumSize(new Dimension(90, 22));
  refreshButton.setPreferredSize(new Dimension(90, 22));
  refreshButton.setOpaque(false);
  refreshButton.setText(I18n.getString("startUpRefresh")); // "Refresh"
  refreshButton.addActionListener(new java.awt.event.ActionListener() {
   public void actionPerformed(ActionEvent e) {
    refreshButton_actionPerformed(e);
    }
   });

  stopShowingCheckBox.setOpaque(false);
  stopShowingCheckBox.setText(I18n.getString("startUpShow")); // "Show this dialog at start"
  stopShowingCheckBox.addActionListener(new java.awt.event.ActionListener() {
   public void actionPerformed(ActionEvent e) { }
   });

  add(buttonPanel, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
  buttonPanel.add(openButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(4, 0, 0, 4), 0, 0));
  buttonPanel.add(cancelButton, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(4, 0, 0, 4), 0, 0));
  buttonPanel.add(Box.createGlue(), new GridBagConstraints(0, 1, 1, 2, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
  add(mainTabPane, new GridBagConstraints(0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
  mainTabPane.add(fileChooser, OPEN_STRING);
  add(stopShowingCheckBox, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0));
  add(headerLabel, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));

  }

 private void setFileChooserButtons () {
  add(refreshButton, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets(0, 2, 1, 1), 0, 0));
  remove(buttonPanel);
  }

 private void setRegularButtons () {
  remove(refreshButton);
  add(buttonPanel, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
  }

 private void mainTabPane_stateChanged (ChangeEvent e) {
  if (currentlySelected != null) {
   currentlySelected.deSelect();
   currentlySelected = null;
   }
  if (mainTabPane.getSelectedComponent() == fileChooser) {
   setFileChooserButtons();
   handleFileSelectionChange( fileChooser.getSelectedFile() );
  } else {
   setRegularButtons();
   openButton.setEnabled( false );
   }
  }
 
 private void fileChooser_actionPerformed (ActionEvent e) {
  String actionCommand = e.getActionCommand();
  if (actionCommand.equals(JFileChooser.APPROVE_SELECTION)) {
   openButton.setEnabled(true);
   openButton.doClick();
  } else if (actionCommand.equals(JFileChooser.CANCEL_SELECTION)) {
   cancelButton.doClick();
   }
  }

 private void refreshButton_actionPerformed (ActionEvent e) {
  initializeFileChooser();
  setTabID( OPEN_TAB_ID );
  }

 protected class StartUpIcon extends javax.swing.JLabel implements java.awt.event.MouseListener {
  protected static final int STANDARD = 1;
  protected static final int DIRECTORY = 3;
  protected boolean isSelected = false;
  protected String file;
  protected boolean needToSave = false;
  protected int type;
  protected java.awt.Component owner;

  public StartUpIcon (String name, javax.swing.ImageIcon icon, String file, boolean needToSave, int type, java.awt.Component owner) {
   super(name, icon, SwingConstants.CENTER);
   this.file = file;
   this.needToSave = needToSave;
   this.type = type;
   this.owner = owner;

   this.setBackground(BACKGROUND_COLOR);
   this.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2));
   this.setVerticalTextPosition(SwingConstants.BOTTOM);
   this.setHorizontalTextPosition(SwingConstants.CENTER);
   java.awt.Dimension size = new java.awt.Dimension(icon.getIconWidth()+4, (icon.getIconHeight() + 24));
   this.setPreferredSize(size);
   this.setMinimumSize(size);
   this.setMaximumSize(size);
   if (type == DIRECTORY) {
    this.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.HAND_CURSOR));
    }
   this.setOpaque(false);
   this.addMouseListener(this);
   }

  protected javax.swing.JPanel getContainer (java.awt.Component topLevelOwner) {
   return null;
   }

  protected javax.swing.JLabel getJLabel (java.awt.Component topLevelOwner) {
   return null;
   }

  protected String getRootPath (java.awt.Component topLevelOwner) {
   return null;
   }

  protected String getRelativePath (String current, String root) {
   return current.substring(root.length());
   }

  protected void changeDirectory (String newDirectory) {
   java.io.File newDir = new java.io.File(newDirectory);
   java.io.File parentDir = newDir.getParentFile();
   JLabel labelToSet = getJLabel(owner);
   String baseDir = getBaseDirString(owner);
   if (owner instanceof javax.swing.JScrollPane) {
    ((javax.swing.JScrollPane) owner).getVerticalScrollBar().setValue(0);
    }
   buildPanel(getContainer(owner), buildVectorFromDirectory(newDir, aliceFilter), needToSave, parentDir, StartUpIcon.STANDARD);
   labelToSet.setText(baseDir + getRelativePath(newDir.getAbsolutePath(), getRootPath(owner)));
   }

  public void deSelect () {
   if (isSelected) {
    currentlySelected = null;
    this.isSelected = false;
    this.setBackground(BACKGROUND_COLOR);
    this.setOpaque(false);
    this.repaint();
    this.setForeground((java.awt.Color) javax.swing.UIManager.get("Label.foreground"));
    }
   }

  public void mouseClicked (java.awt.event.MouseEvent e) {
   if (type == DIRECTORY) {
    changeDirectory(file);
   } else {
    if (!isSelected) {
     isSelected = true;
     if (currentlySelected != null) {
      currentlySelected.deSelect();
      }
     if (!openButton.isEnabled()) {
      openButton.setEnabled(true);
      }
     this.setBackground(SELECTED_COLOR);
     this.setOpaque(true);
     this.setForeground(SELECTED_TEXT_COLOR);
     currentlySelected = this;
     currentlySelected.repaint();
     }
    if (e.getClickCount() == 2) {
     openButton.doClick();
     }
    }
   }
  public void mouseReleased(java.awt.event.MouseEvent e) { }
  public void mousePressed(java.awt.event.MouseEvent e) { }
  public void mouseExited(java.awt.event.MouseEvent e) { }
  public void mouseEntered(java.awt.event.MouseEvent e) { }
  }

 }
